<?php
/**
 * Created by PhpStorm.
 * User: 小蛮哼哼哼
 * Email: 243194993@qq.com
 * Date: 2021/11/17
 * Time: 13:31
 * motto: 现在的努力是为了小时候吹过的牛逼！
 */

declare(strict_types=1);

namespace app\api\controller\v1;

use app\api\controller\Base;
use app\api\controller\Payment;
use app\common\business\Grabbing;
use app\common\business\Lou;
use app\common\business\PlaceOrder as BusObj;
use app\common\business\Run;
use app\common\business\Sex;
use app\common\business\Site;
use app\common\business\Volume;
use app\common\business\Weight;
use app\common\lib\Show;
use app\common\lib\Status;
use EasyWeChat\Factory;
use think\App;
use think\Exception;
use think\helper\Str;
use WeChatPay\Builder;
use WeChatPay\Crypto\Rsa;
use WeChatPay\Util\PemUtil;

class PlaceOrder extends Base
{
    protected $busObj = null;

    public function __construct(App $app)
    {
        $this->busObj = new BusObj();
        parent::__construct($app);
    }

    public function getPlaceOrderConfig()
    {
        $sex = (new Sex())->getListData('id as value,title as name');
        $weight = (new Weight())->getListData("id as value,title as name,money");

        $restriction = (new Grabbing())->getListData('id as value,title as name');
        $volume = (new Volume())->getListData("id as value,title as name,money");
        $lou = (new Lou())->getListData("id as value,title as name,money");
        $qu = (new Site())->getListData("id as value,title as name");

        $run = (new Run())->getRunByDistanceById();
        //dump($lou);exit();
        $result = [
            "sex" => $sex,
            "weight" => $weight,
            "restriction" => $restriction,
            "volume" => $volume,
            "isLou" => $lou,
            "qu" => $qu,
            "run"=>$run
        ];
        return Show::json_show(Status::mini_normal, "ok", $result);
    }

    public function add()
    {
        $param = $this->request->param();
//        if(empty($param['weight'])){
//            return Show::json_show(Status::mini_error,"请选择体重");
//        }
//        //查询重量
//        $weight = (new Weight())->getBaseById($param['weight']);
        //查询体积描述
        if (empty($param['desc'])) {
            return Show::json_show(Status::mini_error, "请选择体积描述");
        }
        $volume = (new Volume())->getBaseById((int)$param['desc']);

        //查询是否上楼
        $lou = (new Lou())->getBaseById($param['isLot']);
        if (empty($volume) || empty($lou)) {
            return Show::json_show(Status::mini_error, "选择错误");
        }
        if ($lou['money'] == 1) {
            $lou['money'] = 0;
        }
        if ($lou['money'] == 0) {
            $money = $volume['money'];
        } else {
            $money = $volume['money'] + ($volume['money'] * $lou['money']);
        }
        $param['money'] = $money;
        try {
            $res = $this->busObj->add($param);
        } catch (\Exception $e) {
            return Show::json_show(Status::mini_error, $e->getMessage());
        }
        if ($res) {
            //计算付款金额
            $notify = (string)url('/api/notify/jsapi', [], true, true);
//            dump($notify);exit();
            $app = Factory::payment(config('wechat.miniPay'));;
            $result = $app->order->unify([
                'body' => '跑腿帮忙',
                'out_trade_no' => $res['order_id'],
                'total_fee' => $money * 100,
                'spbill_create_ip' => $this->request->ip(), // 可选，如不传该参数，SDK 将会自动获取相应 IP 地址
                'notify_url' => $notify, // 支付结果通知网址，如果不设置则会使用配置里的默认地址
                'trade_type' => 'JSAPI', // 请对应换成你的支付方式对应的值类型
                'openid' => $param['openid'],
            ]);
            if ($result['return_code'] == "SUCCESS") {
                if ($result['result_code'] == "SUCCESS") {
                    $res = $app->jssdk->bridgeConfig($result['prepay_id']);
                    if ($res) {
                        return Show::json_show(Status::mini_normal, "ok", Show::json_decode($res));
                    }
                } else {
                    return Show::json_show(Status::mini_error, "业务返回失败");
                }
            } else {
                return Show::json_show(Status::mini_error, $result['return_msg']);
            }
            //return Show::json_show(Status::mini_normal, "成功", $res);
        } else {
            return Show::json_show(Status::mini_error, "操作失败");
        }
    }

    /**
     * 支付
     * @return \think\response\Json|void
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function setPayment()
    {
        $id = $this->request->param('id', 0, 'intval');
        if ($id == 0) {
            return Show::json_show(Status::mini_error, "系统错误");
        }
        try {
            $order = $this->busObj->setPayment($id);
        } catch (\Exception $e) {
            return Show::json_show(Status::mini_error, $e->getMessage());
        }
        if ($order) {
            $notify = (string)url('/api/notify/jsapi', [], true, true);
            $app = Factory::payment(config('wechat.miniPay'));
            $result = $app->order->unify([
                'body' => '跑腿帮忙',
                'out_trade_no' => $order['order_id'],
                'total_fee' => $order['money'] * 100,
                'spbill_create_ip' => $this->request->ip(), // 可选，如不传该参数，SDK 将会自动获取相应 IP 地址
                'notify_url' => $notify, // 支付结果通知网址，如果不设置则会使用配置里的默认地址
                'trade_type' => 'JSAPI', // 请对应换成你的支付方式对应的值类型
                'openid' => $order['openid'],
            ]);
            if ($result['return_code'] == "SUCCESS") {
                if ($result['result_code'] == "SUCCESS") {

                    $res = $app->jssdk->bridgeConfig($result['prepay_id']);
                    if ($res) {
                        return Show::json_show(Status::mini_normal, "ok", Show::json_decode($res));
                    }
                } else {
                    return Show::json_show(Status::mini_error, $result['err_code_des']);
                }
            } else {
                return Show::json_show(Status::mini_error, $result['return_msg']);
            }
        } else {
            return Show::json_show(Status::mini_error, "订单不存在");
        }
    }

    public function cancelPayment()
    {
        $id = $this->request->param('id', 0, 'intval');
        if ($id == 0) {
            return Show::json_show(Status::mini_error, "内部错误");
        }
        try {
            $order = $this->busObj->getBaseById((int)$id);
        } catch (\Exception $e) {
            return Show::json_show(Status::mini_error, $e->getMessage());
        }
        if (!$order) {
            return Show::json_show(Status::mini_error, "订单错误");
        }
        //查询订单是否支付
        $refund_order = date("YmdHis") . Str::random(8);
//        dump();exit();
        if ($order['payStatus'] === 1) {
            $app = Factory::payment(config('wechat.miniPay'));
            $result = $app->refund->byOutTradeNumber($order['order_id'], $refund_order, intval($order['money'] * 100), intval($order['money'] * 100));
            if ($result['return_code'] == "SUCCESS") {
                $update_data = [
                    "status" => Status::mysql_delete,
                    "payStatus" => 2,
                    "refund_time" => time(),
                    "refund_order" => $refund_order,
                    "refund_code" => Show::json_encode($result)
                ];
                try {
                    $res = $this->busObj->updateByData($order['id'], $update_data);
                } catch (\Exception $e) {
                    throw new Exception($e->getMessage());
                }
                if ($res) {
                    return Show::json_show(Status::mini_normal, "删除成功");
                } else {
                    return Show::json_show(Status::mini_error, "删除失败");
                }
            } else {
                return Show::json_show(Status::mini_error, "删除错误");
            }
        }
        //删除订单
        try {
            $res = $this->busObj->updateByData($id, [
                "status" => Status::mysql_delete
            ]);
        } catch (\Exception $e) {
            return Show::json_show(Status::mini_error, $e->getMessage());
        }
        if ($res) {
            return Show::json_show(Status::mini_normal, "取消成功");
        } else {
            return Show::json_show(Status::mini_error, "取消失败");
        }

    }
}